/**
 * 埋点和行为跟踪工具
 * 用于记录用户行为和关键事件
 * @author WeChat Mini Program Team
 * @since 2025-08-14
 */

const Logger = require('./logger')
const Storage = require('./storage')

class Track {
  constructor() {
    this.sessionId = this.generateSessionId()
    this.userId = null
    this.deviceInfo = null
    this.init()
  }

  /**
   * 初始化埋点系统
   */
  async init() {
    try {
      // 获取设备信息
      this.deviceInfo = await wx.getSystemInfo()
      
      // 获取用户ID
      // 兼容 Storage.user.getUserInfo() 和 Storage.getUserInfo()
      const userInfo = (typeof Storage.getUserInfo === 'function')
        ? Storage.getUserInfo()
        : (Storage.user && typeof Storage.user.getUserInfo === 'function' ? Storage.user.getUserInfo() : null)
      if (userInfo) {
        this.userId = userInfo.id
      }
      
      Logger.info('Track system initialized', {
        sessionId: this.sessionId,
        userId: this.userId,
        device: this.deviceInfo
      })
    } catch (error) {
      Logger.error('Failed to initialize track system', error)
    }
  }

  /**
   * 生成会话ID
   */
  generateSessionId() {
    const timestamp = Date.now()
    const random = Math.random().toString(36).substr(2, 9)
    return `${timestamp}_${random}`
  }

  /**
   * 设置用户ID
   */
  setUserId(userId) {
    this.userId = userId
    Logger.info('Track user set', { userId })
  }

  /**
   * 页面浏览埋点
   */
  trackPageView(path, params = {}) {
    this.track('page_view', {
      path,
      params,
      timestamp: Date.now()
    })
  }

  /**
   * 页面停留时间埋点
   */
  trackPageStay(path, duration) {
    this.track('page_stay', {
      path,
      duration,
      timestamp: Date.now()
    })
  }

  /**
   * 点击事件埋点
   */
  trackClick(element, elementType = 'button', extra = {}) {
    this.track('click', {
      element,
      elementType,
      ...extra,
      timestamp: Date.now()
    })
  }

  /**
   * 接口调用埋点
   */
  trackApiCall(api, method, success, duration, error = null) {
    this.track('api_call', {
      api,
      method,
      success,
      duration,
      error,
      timestamp: Date.now()
    })
  }

  /**
   * 分享埋点
   */
  trackShare(type, content, extra = {}) {
    this.track('share', {
      type, // 'miniprogram', 'timeline'
      content,
      ...extra,
      timestamp: Date.now()
    })
  }

  /**
   * 搜索埋点
   */
  trackSearch(keyword, category, resultCount) {
    this.track('search', {
      keyword,
      category,
      resultCount,
      timestamp: Date.now()
    })
  }

  /**
   * 表单提交埋点
   */
  trackFormSubmit(formType, success, error = null) {
    this.track('form_submit', {
      formType,
      success,
      error,
      timestamp: Date.now()
    })
  }

  /**
   * 性能埋点
   */
  trackPerformance(metric, value, extra = {}) {
    this.track('performance', {
      metric,
      value,
      ...extra,
      timestamp: Date.now()
    })
  }

  /**
   * 错误埋点
   */
  trackError(type, message, stack, extra = {}) {
    this.track('error', {
      type,
      message,
      stack,
      ...extra,
      timestamp: Date.now()
    })
  }

  /**
   * 自定义事件埋点
   */
  trackCustomEvent(event, data = {}) {
    this.track('custom_event', {
      event,
      data,
      timestamp: Date.now()
    })
  }

  /**
   * 基础埋点方法
   */
  track(eventType, eventData) {
    const trackData = {
      sessionId: this.sessionId,
      userId: this.userId,
      eventType,
      eventData,
      deviceInfo: {
        platform: this.deviceInfo?.platform,
        version: this.deviceInfo?.version,
        model: this.deviceInfo?.model,
        pixelRatio: this.deviceInfo?.pixelRatio,
        screenWidth: this.deviceInfo?.screenWidth,
        screenHeight: this.deviceInfo?.screenHeight
      },
      timestamp: Date.now()
    }

    // 记录到本地日志
    Logger.info(`[TRACK] ${eventType}`, trackData)

    // TODO: 发送到埋点服务器
    this.sendToServer(trackData)

    // 本地存储（用于离线上报）
    this.storeLocally(trackData)
  }

  /**
   * 发送到埋点服务器
   */
  async sendToServer(trackData) {
    try {
      // 这里应该调用埋点API
      // await TrackService.report(trackData)
      
      // 暂时使用模拟
      if (wx.getStorageSync('TRACK_DEBUG')) {
        console.log('[TRACK_SEND]', trackData)
      }
    } catch (error) {
      Logger.error('Failed to send track data', error)
      
      // 发送失败时存储到本地队列
      this.storeToQueue(trackData)
    }
  }

  /**
   * 本地存储埋点数据
   */
  storeLocally(trackData) {
    try {
      const localTracks = Storage.get('local_tracks', [])
      localTracks.push(trackData)
      
      // 只保留最近100条记录
      if (localTracks.length > 100) {
        localTracks.splice(0, localTracks.length - 100)
      }
      
      Storage.set('local_tracks', localTracks)
    } catch (error) {
      Logger.error('Failed to store track data locally', error)
    }
  }

  /**
   * 存储到上报队列
   */
  storeToQueue(trackData) {
    try {
      const trackQueue = Storage.get('track_queue', [])
      trackQueue.push(trackData)
      
      // 队列过长时删除旧数据
      if (trackQueue.length > 500) {
        trackQueue.splice(0, 100)
      }
      
      Storage.set('track_queue', trackQueue)
    } catch (error) {
      Logger.error('Failed to store track data to queue', error)
    }
  }

  /**
   * 批量上报队列中的埋点数据
   */
  async flushQueue() {
    try {
      const trackQueue = Storage.get('track_queue', [])
      if (trackQueue.length === 0) return

      // 批量发送
      // await TrackService.batchReport(trackQueue)
      
      Logger.info('Track queue flushed', { count: trackQueue.length })
      
      // 清空队列
      Storage.remove('track_queue')
    } catch (error) {
      Logger.error('Failed to flush track queue', error)
    }
  }

  /**
   * 获取本地埋点数据
   */
  getLocalTracks() {
    return Storage.get('local_tracks', [])
  }

  /**
   * 清空本地埋点数据
   */
  clearLocalTracks() {
    Storage.remove('local_tracks')
    Storage.remove('track_queue')
  }

  /**
   * 启用调试模式
   */
  enableDebug() {
    Storage.set('TRACK_DEBUG', true)
    Logger.info('Track debug mode enabled')
  }

  /**
   * 禁用调试模式
   */
  disableDebug() {
    Storage.remove('TRACK_DEBUG')
    Logger.info('Track debug mode disabled')
  }
}

// 创建单例实例
const instance = new Track()

module.exports = instance
